﻿using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using HPAGMRestAPIWrapper;

namespace AGMRestAPITest
{
    /// <summary>
    /// Summary description for AGMTestTest
    /// </summary>
    [TestClass]
    public class AGMTestTest
    {
        public AGMTestTest()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        private TestContext _testContextInstance;

        private static AGMConnection _connection;
        private static AGMTestFolders _testfolders;
        private static AGMTests _tests;

        private AGMTestFolder _testfolder;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return _testContextInstance;
            }
            set
            {
                _testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        [ClassInitialize]
        public static void MyClassInitialize(TestContext testContext)
        {
            _connection = new AGMConnection(AGMSetting.SERVERNAME, AGMSetting.USERNAME, AGMSetting.PASSWORD);
            _testfolders = new AGMTestFolders(_connection);
            _tests = new AGMTests(_connection);
        }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        [ClassCleanup]
        public static void MyClassCleanup()
        {
            if (_connection != null)
                _connection.Logoff();
        }
        //
        // Use TestInitialize to run code before running each test 
        [TestInitialize]
        public void MyTestInitialize()
        {
            var root = _testfolders.Get(AGMSetting.ROOT_TESTFOLDER_ID);

            #region Add test folder
            _testfolder = root.CreateFolder("AGMREST Test Folder");
            Assert.IsTrue(_testfolders.IsExists(_testfolder.Id.Value), "Create test folder failed.");
            #endregion
        }
        //
        // Use TestCleanup to run code after each test has run
        [TestCleanup]
        public void MyTestCleanup()
        {
            #region Delete test folder
            _testfolders.Get(_testfolder.Id.Value).Delete();
            Assert.IsTrue(!_testfolders.IsExists(_testfolder.Id.Value), "delete test folder fail.");
            #endregion
        }
        //
        #endregion

        [TestMethod]
        public void Test_UpdateFolder()
        {
            #region Update test folder
            _testfolder.SetUpdateField("description", "Description of Test Folder");
            var updFolder = _testfolder.Update();
            Assert.AreEqual(updFolder.GetField("description").Value, "Description of Test Folder", "Update test folder failed.");
            #endregion
        }

        [TestMethod]
        public void Test_AddUpdateDelete()
        {
            #region add test item
            var addedTest = _testfolder.AddTest("New Test");

            var testId = addedTest.Id.Value;
            Assert.IsTrue(_tests.Get(testId) != null, "Add test fail.");
            #endregion

            #region update test item
            addedTest.SetUpdateField("owner", "tina");
            var updatedTest = addedTest.Update();
            Assert.AreEqual(updatedTest.GetField("owner").Value, "tina", "Update test fail.");
            #endregion

            #region delete test item
            updatedTest.Delete();
            Assert.IsTrue(!_tests.IsExists(testId), "delete test fail.");
            #endregion
        }

        [TestMethod]
        public void Test_UploadDownLoadDeleteAttachmentOnFolder()
        {
            _testfolder.UploadAttachment(@"Test.txt");
            Assert.IsTrue(_testfolder.IsAttachmentExists("Test.txt"), "Uploaded attachement is not exists.");

            _testfolder.DownloadAttachment(@"Test.txt", @"c:\Test.txt");
            Assert.IsTrue(Helper.CheckAttachment(@"C:\Test.txt"), "Downloaded attachement is not exists.");

            _testfolder.DeleteAttachment(@"Test.txt");
            Assert.IsFalse(_testfolder.IsAttachmentExists("Test.txt"), "Uploaded attachement is not exists.");
        }

        [TestMethod]
        public void Test_UploadDownLoadDeleteAttachment()
        {
            #region add test item
            var addedTest = _testfolder.AddTest("New Test");

            var testId = addedTest.Id.Value;
            Assert.IsTrue(_tests.Get(testId) != null, "Add test fail.");
            #endregion

            addedTest.UploadAttachment(@"Test.txt");
            Assert.IsTrue(addedTest.IsAttachmentExists("Test.txt"), "Uploaded attachement is not exists.");

            addedTest.DownloadAttachment(@"Test.txt", @"c:\Test.txt");
            Assert.IsTrue(Helper.CheckAttachment(@"C:\Test.txt"), "Downloaded attachement is not exists.");

            addedTest.DeleteAttachment(@"Test.txt");
            Assert.IsFalse(addedTest.IsAttachmentExists("Test.txt"), "Uploaded attachement is not exists.");

            #region delete test item
            addedTest.Delete();
            Assert.IsTrue(!_tests.IsExists(testId), "delete test fail.");
            #endregion
        }

        [TestMethod]
        public void Test_AddUpdateDeleteStep()
        {
            #region add test item
            var addedTest = _testfolder.AddTest("New Test");

            var testId = addedTest.Id.Value;
            Assert.IsTrue(_tests.Get(testId) != null, "Add test fail.");
            #endregion

            #region add test step
            var addedTestStep = addedTest.AddStep("new step from API", "a new step", "a new expected");
            Assert.AreEqual(addedTestStep.GetField("parent-id").Value, testId.ToString(), "Add test step fail.");
            #endregion

            #region update test step
            var updatedTestStep = addedTestStep.Update("updated name", "updated description", "updated expected");
            Assert.AreEqual(updatedTestStep.GetField("name").Value, "updated name", "step name is not updated.");
            Assert.AreEqual(updatedTestStep.GetField("description").Value, "updated description", "step description is not updated.");
            Assert.AreEqual(updatedTestStep.GetField("expected").Value, "updated expected", "step expected is not updated.");
            #endregion

            #region delete test step
            int stepsCountBeforeDelete = addedTest.GetSteps().Count;
            updatedTestStep.Delete();
            int stepsCountAfterDelete = addedTest.GetSteps().Count;
            Assert.AreEqual(stepsCountBeforeDelete - stepsCountAfterDelete, 1, "delete step fail.");
            #endregion
        }

        [TestMethod]
        public void Test_MoveUpMoveDownStep()
        {
            #region add test item
            var addedTest = _testfolder.AddTest("New Test");
            var testId = addedTest.Id.Value;
            Assert.IsTrue(_tests.Get(testId) != null, "Add test fail.");
            #endregion

            #region add test steps
            var addedTestStep1 = addedTest.AddStep("new step 1", "1 new step", "1 new expected");
            var addedTestStep2 = addedTest.AddStep("new step 2", "2 new step", "2 new expected");
            var addedTestStep3 = addedTest.AddStep("new step 3", "3 new step", "3 new expected");
            #endregion

            #region moveup test step
            var moveupTestStep = addedTestStep3.MoveUp();
            Assert.AreEqual(moveupTestStep.GetField("step-order").Value, "2", "step move up fail.");
            #endregion

            #region movedown test step
            var movedownTestStep = addedTestStep1.MoveDown();
            Assert.AreEqual(movedownTestStep.GetField("step-order").Value, "2", "step move down fail.");
            #endregion
        }
    }
}
